package services

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/pkg/db/mysql"
	"TaskAssignmentSystem/pkg/utils"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"strings"
)

type MessageService struct {
}

const (
	MsgStatusNormal          = 1
	MsgClassificationGlobal  = 1 //通知分类-全局通知
	MsgClassificationProject = 2 //通知分类-项目通知
)

func (m *MessageService) SendMessage(projectId, MsgContent string) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var msg dao.SystemMsg
		msg.Permissions = projectId
		msg.Content = MsgContent
		msg.Status = 1
		if err := tx.Model(&dao.SystemMsg{}).Create(&msg).Error; err != nil {
			return err
		} else {
			//查询当前所有有项目权限的用户
			var userRestrictions []dao.SystemUserRestriction
			tx.Model(&dao.SystemUserRestriction{}).Where("project_id = ?", projectId).Find(&userRestrictions)
			var userMessages []dao.UserMessage
			for _, restriction := range userRestrictions {
				userMessages = append(userMessages, dao.UserMessage{
					MessageId:    msg.Id,
					ProjectId:    projectId,
					SystemUserId: restriction.SystemUserId,
					Status:       0,
				})
			}
			if len(userMessages) > 0 {
				if err := tx.Model(&dao.UserMessage{}).Create(&userMessages).Error; err != nil {
					return err
				}
			}
		}
		return nil
	})

}

func (m *MessageService) BatchRemoveMsg(ids []uint) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var msg dao.Common[dao.SystemMsg]
		msg.Tx = tx
		if err := msg.RemoveUnscopedWhere(map[string]interface{}{"id": ids}).Error; err != nil {
			return err
		}
		if err := tx.Model(&dao.UserMessage{}).Unscoped().Where("message_id IN (?)", ids).Delete(&dao.UserMessage{}).Error; err != nil {
			return err
		}
		return nil
	})
}

func (m *MessageService) SendMessageGlobal(msgType int, param map[string]string) (err error) {
	if utils.StringIsEmpty(param["msg_way"]) {
		return errors.New("通知形式不能为空！")
	}
	if _, err := utils.StringToInt(param["msg_way"]); err != nil {
		return errors.New("通知形式参数异常！")
	}
	if utils.StringIsEmpty(param["content"]) {
		return errors.New("通知内容不能为空！")
	}

	var userIds = []string{}
	var teamNumbers = []string{}
	var teamService TeamService
	if msgType == 1 {
		//全部团队
		if utils.StringIsEmpty(param["team_number"]) {
			teamNumbers, err = teamService.FindAllTeamNumber()
			if err != nil {
				return errors.New("服务器链接异常")
			}
		}
	} else if msgType == 2 {
		//指定团队
		//校验团队存在
		teamNumberList := strings.Split(param["team_number"], ",")
		for _, number := range teamNumberList {
			exist, err := teamService.VerifyTeamNumber(number)
			if err != nil {
				return errors.New("服务器连接异常")
			}
			if !exist {
				//不校验zxz或者ZXZ团队
				if number == "zxz" || number == "ZXZ" {
					continue
				} else {
					//不存在
					return errors.New(fmt.Sprintf("团队[%s]不存在,无法发送通知。", number))
				}
			}
			teamNumbers = append(teamNumbers, number)
		}
	} else if msgType == 3 {
		//个人
		if utils.StringIsEmpty(param["user"]) {
			return errors.New("通知用户不能为空！")
		}
		var userService UserService
		userIdList := strings.Split(param["user"], ",")
		for _, userId := range userIdList {
			exist, userInfo, err := userService.VerifyUser(userId)
			if err != nil {
				return err
			}
			if !exist {
				return errors.New("该用户不存在")
			}
			userIds = append(userIds, userInfo.UserId)

		}
	} else {
		return errors.New("全局通知类型异常")
	}

	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var msg dao.SystemMsg
		msg.MsgClassification = MsgClassificationGlobal
		msg.MsgType = msgType
		msg.MsgWay, _ = utils.StringToUint(param["msg_way"])
		msg.Content = param["content"]
		msg.Status = MsgStatusNormal
		if err := tx.Model(&dao.SystemMsg{}).Create(&msg).Error; err != nil {
			return err
		} else {
			way, _ := utils.StringToInt(param["msg_way"])
			//全部团队
			if msgType == 1 {
				//发全局通知
				if msg.MsgWay == 1 {
					var common CommonService[dao.SystemUser]
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz'"))
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz' or user_id in (SELECT user_id from tas_system_team WHERE status = 1)"))
					if res, err := common.FindNoPreloadAll(); err == nil {
						var userCommon dao.Common[dao.UserMsgInfo]
						userMsgInfoList := make([]dao.UserMsgInfo, len(res))
						for index, users := range res {
							var userMsgInfo dao.UserMsgInfo
							userMsgInfo.MsgId = msg.Id
							userMsgInfo.SystemUserId = users.UserId
							userMsgInfoList[index] = userMsgInfo
						}
						for i := 0; i < len(userMsgInfoList); i += 1000 {
							end := i + 1000
							if end > len(userMsgInfoList) {
								end = len(userMsgInfoList)
							}
							if err := userCommon.Create(userMsgInfoList[i:end]).Error; err != nil {
								return err
							}
						}
						if err := tx.Model(&dao.SystemMsg{}).Where("id = ?", msg.Id).Update("send_count", len(res)).Error; err != nil {
							return err
						}
						return nil
					}
				} else if msg.MsgWay == 2 { //发邮件
					/*if err := utils.SendEmail("33428612@qq.com", "全局通知", "你好"); err != nil {
						return err
					}*/
					var common CommonService[dao.SystemUser]
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz' "))
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz' or user_id in (SELECT user_id from tas_system_team WHERE status = 1)"))
					common.WhereStr = append(common.WhereStr, fmt.Sprintf("email is not null "))
					common.WhereStr = append(common.WhereStr, fmt.Sprintf("email != '' "))
					if res, err := common.FindNoPreloadAll(); err == nil {
						//toEmail := make([]string, len(res))
						for _, r := range res {
							//toEmail[i] = r.Email
							utils.SendEmail(r.Email, "宅小职消息通知", msg.Content)
						}
						//utils.BatchSendEmail(toEmail, "宅小职消息通知", msg.Content)
						return nil
					}
				} else if msg.MsgWay == 3 { //发手机短信
					/*if err := utils.SendSms("13407176920", "你好"); err != nil {
						return err
					}*/
					var common CommonService[dao.SystemUser]
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz' "))
					//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number != 'zxz' or user_id in (SELECT user_id from tas_system_team WHERE status = 1)"))
					common.WhereStr = append(common.WhereStr, fmt.Sprintf("phont is not null "))
					common.WhereStr = append(common.WhereStr, fmt.Sprintf("phont != '' "))
					if res, err := common.FindNoPreloadAll(); err == nil {
						for _, r := range res {
							utils.SendSms(r.Phone, msg.Content)
						}
						return nil
					}
				}
			}
			if msgType == 2 {
				//发全局通知
				if msg.MsgWay == 1 {
					noticeNum := 0
					//团队
					for _, number := range teamNumbers {
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.TeamNumber = number
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v'", number))
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v' or user_id in (SELECT user_id from tas_system_team WHERE status = 1 and team_number = '%v')", number, number))
							if res, err := common.FindNoPreloadAll(); err == nil {
								var userCommon dao.Common[dao.UserMsgInfo]
								userMsgInfoList := make([]dao.UserMsgInfo, len(res))
								for index, users := range res {
									var userMsgInfo dao.UserMsgInfo
									userMsgInfo.MsgId = msg.Id
									userMsgInfo.SystemUserId = users.UserId
									userMsgInfoList[index] = userMsgInfo
								}
								for i := 0; i < len(userMsgInfoList); i += 1000 {
									end := i + 1000
									if end > len(userMsgInfoList) {
										end = len(userMsgInfoList)
									}
									if err := userCommon.Create(userMsgInfoList[i:end]).Error; err != nil {
										return err
									}
								}
								noticeNum += len(res)
							}
						}
					}
					if err := tx.Model(&dao.SystemMsg{}).Where("id = ?", msg.Id).Update("send_count", noticeNum).Error; err != nil {
						return err
					}
					return nil
				} else if msg.MsgWay == 2 { //发邮件
					for _, number := range teamNumbers {
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.TeamNumber = number
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v'", number))
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v' or user_id in (SELECT user_id from tas_system_team WHERE status = 1 and team_number = '%v')", number, number))
							if res, err := common.FindNoPreloadAll(); err == nil {
								//toEmail := make([]string, len(res))
								for _, users := range res {
									if utils.StringIsNotEmpty(users.Email) {
										//toEmail[i] = users.Email
										utils.SendEmail(users.Email, "宅小职消息通知", msg.Content)
									}
								}
								//utils.BatchSendEmail(toEmail, "宅小职消息通知", msg.Content)
							}
						}
					}
					return nil
				} else if msg.MsgWay == 3 { //发手机短信
					for _, number := range teamNumbers {
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.TeamNumber = number
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							//common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v'", number))
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("team_number = '%v' or user_id in (SELECT user_id from tas_system_team WHERE status = 1 and team_number = '%v')", number, number))
							if res, err := common.FindNoPreloadAll(); err == nil {
								for _, users := range res {
									if utils.StringIsNotEmpty(users.Phone) {
										if err := utils.SendSms(users.Phone, msg.Content); err != nil {
											return err
										}
									}
								}
							}
						}
					}
					return nil
				}
			} else if msgType == 3 {
				//发全局通知
				if msg.MsgWay == 1 {
					noticeNum := 0
					for _, userId := range userIds {
						//个人
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.UserId = userId
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("user_id = '%v'", msgWay.UserId))
							if res, err := common.First(); err == nil {
								var userCommon dao.Common[dao.UserMsgInfo]
								var userMsgInfo dao.UserMsgInfo
								userMsgInfo.MsgId = msg.Id
								userMsgInfo.SystemUserId = res.UserId
								if err := userCommon.CreateOne(userMsgInfo).Error; err != nil {
									return err
								}
							}
						}
						noticeNum += 1
					}
					if err := tx.Model(&dao.SystemMsg{}).Where("id = ?", msg.Id).Update("send_count", noticeNum).Error; err != nil {
						return err
					}
					return nil
				} else if msg.MsgWay == 2 { //发邮件
					for _, userId := range userIds {
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.UserId = userId
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("user_id = '%v'", msgWay.UserId))
							if res, err := common.First(); err == nil {
								if utils.StringIsNotEmpty(res.Email) {
									if err := utils.SendEmail(res.Email, "宅小职消息通知", msg.Content); err != nil {
										return err
									}
								}
							}
						}
					}
					return nil
				} else if msg.MsgWay == 3 { //发手机短信
					for _, userId := range userIds {
						var msgWay dao.SystemMsgWay
						msgWay.MessageId = msg.Id
						msgWay.MsgWay = way
						msgWay.UserId = userId
						if err := tx.Model(&dao.SystemMsgWay{}).Create(&msgWay).Error; err != nil {
							return err
						} else {
							var common CommonService[dao.SystemUser]
							common.WhereStr = append(common.WhereStr, fmt.Sprintf("user_id = '%v'", msgWay.UserId))
							if res, err := common.First(); err == nil {
								if utils.StringIsNotEmpty(res.Phone) {
									if err := utils.SendSms(res.Phone, msg.Content); err != nil {
										return err
									}
								}
							}
						}
					}
					return nil
				}
			}
		}
		return nil
	})
}

type SystemUserRestriction struct {
	dao.SystemUserRestriction
	UserId string `json:"user_id"`
}

func (m *MessageService) SendMessageProject(param map[string]string) (err error) {
	if utils.StringIsEmpty(param["content"]) {
		return errors.New("通知内容不能为空！")
	}
	if utils.StringIsEmpty(param["permissions"]) {
		return errors.New("项目权限不能为空！")
	}
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var msg dao.SystemMsg
		msg.MsgClassification = MsgClassificationProject
		msg.Content = param["content"]
		msg.Permissions = param["permissions"]
		msg.Status = MsgStatusNormal
		if err := tx.Model(&dao.SystemMsg{}).Create(&msg).Error; err != nil {
			return err
		} else {
			//查询当前所有有项目权限的用户
			var userRestrictions []SystemUserRestriction
			tx.Model(&SystemUserRestriction{}).Select("DISTINCT tas_system_user_restriction.system_user_id system_user_id, tas_system_user_restriction.project_id project_id,tas_system_user.user_id user_id").Joins("left join tas_system_user on tas_system_user_restriction.system_user_id = tas_system_user.id").Where("project_id = ?", msg.Permissions).Find(&userRestrictions)
			//var userMessages []dao.UserMessage
			var userMessages []dao.UserMsgInfo
			for _, restriction := range userRestrictions {
				userMessages = append(userMessages, dao.UserMsgInfo{
					MsgId:        msg.Id,
					SystemUserId: restriction.UserId,
					Status:       0,
					Type:         0,
				})
			}
			if len(userMessages) > 0 {
				for i := 0; i < len(userMessages); i += 1000 {
					end := i + 1000
					if end > len(userMessages) {
						end = len(userMessages)
					}
					if err := tx.Model(&dao.UserMsgInfo{}).Create(userMessages[i:end]).Error; err != nil {
						return err
					}
				}
			}
		}
		return nil
	})
}

func (m *MessageService) BatchRemoveMsgNew(ids []uint) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var msg dao.Common[dao.SystemMsg]
		msg.Tx = tx
		if err := msg.RemoveUnscopedWhere(map[string]interface{}{"id": ids}).Error; err != nil {
			return err
		}
		var msgWay dao.Common[dao.SystemMsgWay]
		msg.Tx = tx
		if err := msgWay.RemoveUnscopedWhere(map[string]interface{}{"message_id": ids}).Error; err != nil {
			return err
		}
		if err := tx.Model(&dao.UserMsgInfo{}).Unscoped().Where("msg_id IN (?)", ids).Delete(&dao.UserMsgInfo{}).Error; err != nil {
			return err
		}
		return nil
	})
}
